//----------------------------------*-C++-*----------------------------------//
/*!
 * \file   Cross_Section.cc
 * \author Jeremy Roberts
 * \date   Jul 20, 2011
 * \brief  Cross_Section member definitions.
 * \note   Copyright (C) 2011 Jeremy Roberts. 
 */
//---------------------------------------------------------------------------//
// $Rev::                                               $:Rev of last commit
// $Author::                                            $:Author of last commit
// $Date::                                              $:Date of last commit
//---------------------------------------------------------------------------//

#include <iostream>
#include <cstdio>

#include "material/Cross_Section.hh"

namespace slabtran
{

// Constructor
Cross_Section::Cross_Section(const int number_groups, const int legendre_order)
  :  d_number_groups(number_groups),
     d_legendre_order(legendre_order),
     d_downscatter(true),
     d_adjoint(false),
     d_sigma(number_groups, 0.0),
     d_sigma_a(number_groups, 0.0),
     d_sigma_f(number_groups, 0.0),
     d_nu(number_groups, 0.0),
     d_chi(number_groups, 0.0),
     // S is ng*ng, but we don't allocate elements until needed
     d_S(number_groups, S_Row(number_groups)),
     // lower bounds defaulted to 0
     d_group_lower_bound(Vec_Int(number_groups, 0), Vec_Int(number_groups, 0)),
     // upper bounds defaulted to -1 (i.e defaults imply no group loop)
     d_group_upper_bound(Vec_Int(number_groups, -1), Vec_Int(number_groups, -1))
{
  Require(d_number_groups > 0);
  Require(d_legendre_order >= 0);
  Require(d_sigma.size() == d_number_groups);
  Require(d_sigma_a.size() == d_number_groups);
  Require(d_sigma_f.size() == d_number_groups);
  Require(d_nu.size() == d_number_groups);
  Require(d_chi.size() == d_number_groups);
  Require(d_S.size() == d_number_groups);
  Require(d_S[0].size() == d_number_groups);
  Require(d_group_lower_bound[0].size() == d_number_groups);
  Require(d_group_upper_bound[1].size() == d_number_groups);
  Require(d_group_lower_bound[0].size() == d_number_groups);
  Require(d_group_upper_bound[1].size() == d_number_groups);
}

// print
void Cross_Section::print() const
{
  using std::cout;
  using std::endl;
  using std::printf;

  cout << "        name of material: " << d_name << endl;
  cout << "        number of groups: " << d_number_groups << endl;
  cout << "          legendre order: " << d_legendre_order << endl;

  cout << "   g     SigmaT       SigmaA       SigmaF         nu          chi      ";
  for (int g = 0; g < d_number_groups; g++)
    for (int l = 0; l < d_legendre_order+1; l++)
      printf(" S(g<-%2i,%2i) ", g, l);
  cout << endl;
  cout << "  ---  -----------  -----------  -----------  -----------  ----------- ";
  for (int g = 0; g < d_number_groups; g++)
    for (int l = 0; l < d_legendre_order+1; l++)
      cout << " ----------- ";
  cout << endl;
  // g1  T  A  F  N  X  S1>1 S2>1 ...
  // g2 ...
  if (d_adjoint) cout << " warning: adjoint active!" << endl;
  for (int g = 0; g < d_number_groups; g++)
  {
    // print group data
    printf("%4i   %8.5e  %8.5e  %8.5e  %8.5e  %8.5e", g,
           d_sigma[g], d_sigma_a[g], d_sigma_f[g], d_nu[g], d_chi[g]);
    // print scattering data -- blank for non existent
    for (int gp = 0; gp < group_lower_bound(g); gp++)
      for (int l = 0; l < d_legendre_order + 1; l++)
        printf("       d     ");
    for (int gp = group_lower_bound(g); gp <= group_upper_bound(g); gp++)
      for (int l = 0; l < d_legendre_order + 1; l++)
        printf("  %8.5e", sigma_s(g, gp, l));
    for (int gp = group_upper_bound(g) + 1; gp < d_number_groups; gp++)
      for (int l = 0; l < d_legendre_order + 1; l++)
        printf("       u     ");
    cout << endl;
  }
  cout << endl;

}

} // end namespace slabtran

//---------------------------------------------------------------------------//
//              end of Cross_Section.cc
//---------------------------------------------------------------------------//
